package com.cwm.frame4.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cwm.common.message.MailProperty;
import com.cwm.common.utils.HashUtil;
import com.cwm.frame4.entity.RheaMails;
import com.cwm.frame4.service.IRheaMailsService;
import com.cwm.frame4.service.MailService;
import com.cwm.common.message.MailMessage;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Throwables;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * Mail Service Implementation
 *
 * @author Bill
 * @version 1.0
 * @since 2021-11-26
 */
@Slf4j
@Service
public class MailServiceImpl implements MailService {

    private final String profile;
    private final MailProperty mailProperty;
    private final MessageServiceImpl messageService;
    private final IRheaMailsService mailsRepository;
    private final ObjectMapper objectMapper;

    public MailServiceImpl(
            Environment env, MailProperty mailProperty,
            MessageServiceImpl messageService, IRheaMailsService mailsRepository,
            ObjectMapper objectMapper) {
        profile = env.getProperty("SPRING_PROFILES_ACTIVE");
        this.mailProperty = mailProperty;
        this.messageService = messageService;
        this.mailsRepository = mailsRepository;
        this.objectMapper = objectMapper;
    }

    @Override
    public void notifyOperator(Throwable e) {
        if ("null".equals(profile) || "dev".equals(profile)) {
            log.info("notification is not for dev or default env");
            return;
        }
        String stackTraceAsString = Throwables.getStackTraceAsString(e);
        String stackMd5 = HashUtil.md5(stackTraceAsString);
        if (mailsRepository.count(Wrappers.<RheaMails>lambdaQuery().eq(RheaMails::getContentMd5, stackMd5)) > 0L) {
            log.warn("duplicate exception stack, ignored");
            return;
        }

        StringBuilder subject = new StringBuilder();
        subject.append('[').append(profile).append(']');
        subject.append(" | 系统告警 | Dione | Nexlabel | ");
        LocalDateTime now = LocalDateTime.now();
        subject.append(now.toString());
        StringBuilder content = new StringBuilder();
        content.append("错误堆栈");
        content.append("<pre>").append(stackTraceAsString).append("</pre>");
        String subjectString = subject.toString();
        String contentString = content.toString();
        List<String> recipients = mailProperty.getRecipients();
        String recipientsJsonString;
        try {
            recipientsJsonString = objectMapper.writeValueAsString(recipients);
        } catch (JsonProcessingException jsonProcessingException) {
            log.error("json error, quit", jsonProcessingException);
            return;
        }

        RheaMails mail = RheaMails.builder()
                .messageId(UUID.randomUUID().toString().replaceAll("-", ""))
                .subject(subjectString)
                .content(contentString)
                .contentMd5(stackMd5)
                .recipients(recipientsJsonString)
                .build();
        mailsRepository.save(mail);
        MailMessage mailMessage = MailMessage.builder()
                .messageID(mail.getMessageId())
                .build();
        try {
            messageService.pubTopicMail(mailMessage);
        } catch (Throwable exception) {
            log.error("pub topic mail error", exception);
        }
    }

}
